<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>工厂模式（Factory Pattern）</title>
  <!-- 
  工厂模式（Factory Pattern）是一种创建对象的设计模式，它提供了一种创建对象的接口，但将实际的对象创建过程延迟到子类中。工厂模式的主要目的是将对象的创建与使用分离，以提高代码的灵活性和可维护性。

  ### 工厂模式的分类

  工厂模式主要有以下几种类型：

  1. **简单工厂模式**：根据提供的信息创建对象，通常通过一个静态方法来实现。
  2. **工厂方法模式**：定义一个创建对象的接口，由子类决定实例化哪一个类。
  3. **抽象工厂模式**：提供一个创建一系列相关或相互依赖对象的接口，而无需指定它们的具体类。

  ### 1. 简单工厂模式

  简单工厂模式使用一个工厂类来创建对象。这个工厂类根据传入的参数决定实例化哪个类。

  #### 示例：

  ```javascript
  class Car {
      constructor(brand) {
          this.brand = brand;
      }
  }

  class CarFactory {
      static createCar(brand) {
          return new Car(brand);
      }
  }

  // 使用示例
  const myCar = CarFactory.createCar('Toyota');
  console.log(myCar.brand); // 输出: "Toyota"
  ```

  ### 2. 工厂方法模式

  工厂方法模式通过定义一个接口来创建对象，具体的实现由子类来完成。这样可以扩展新的产品，而不需要修改现有的代码。

  #### 示例：

  ```javascript
  // 产品接口
  class Car {
      drive() {
          throw new Error("This method must be implemented.");
      }
  }

  // 具体产品
  class Toyota extends Car {
      drive() {
          console.log("Driving a Toyota.");
      }
  }

  class Honda extends Car {
      drive() {
          console.log("Driving a Honda.");
      }
  }

  // 工厂接口
  class CarFactory {
      createCar() {
          throw new Error("This method must be implemented.");
      }
  }

  // 具体工厂
  class ToyotaFactory extends CarFactory {
      createCar() {
          return new Toyota();
      }
  }

  class HondaFactory extends CarFactory {
      createCar() {
          return new Honda();
      }
  }

  // 使用示例
  const toyotaFactory = new ToyotaFactory();
  const myToyota = toyotaFactory.createCar();
  myToyota.drive(); // 输出: "Driving a Toyota."
  ```

  ### 3. 抽象工厂模式

  抽象工厂模式提供一个创建一系列相关或相互依赖对象的接口。通常用于创建多个产品族。

  #### 示例：

  ```javascript
  // 抽象产品
  class Car {
      drive() {
          throw new Error("This method must be implemented.");
      }
  }

  class Bike {
      ride() {
          throw new Error("This method must be implemented.");
      }
  }

  // 具体产品
  class ToyotaCar extends Car {
      drive() {
          console.log("Driving a Toyota Car.");
      }
  }

  class HondaCar extends Car {
      drive() {
          console.log("Driving a Honda Car.");
      }
  }

  class YamahaBike extends Bike {
      ride() {
          console.log("Riding a Yamaha Bike.");
      }
  }

  class HondaBike extends Bike {
      ride() {
          console.log("Riding a Honda Bike.");
      }
  }

  // 抽象工厂
  class VehicleFactory {
      createCar() {
          throw new Error("This method must be implemented.");
      }
      
      createBike() {
          throw new Error("This method must be implemented.");
      }
  }

  // 具体工厂
  class ToyotaFactory extends VehicleFactory {
      createCar() {
          return new ToyotaCar();
      }
      
      createBike() {
          return new YamahaBike();
      }
  }

  class HondaFactory extends VehicleFactory {
      createCar() {
          return new HondaCar();
      }
      
      createBike() {
          return new HondaBike();
      }
  }

  // 使用示例
  const toyotaFactory = new ToyotaFactory();
  const myToyotaCar = toyotaFactory.createCar();
  myToyotaCar.drive(); // 输出: "Driving a Toyota Car."
  ```

  ### 工厂模式的优缺点

  #### 优点：

  1. **解耦**：工厂模式将对象的创建与使用分离，使得代码更加灵活。
  2. **易于扩展**：可以通过增加新的工厂和产品类来扩展系统，而不需要修改现有代码。
  3. **集中管理**：所有对象的创建都集中在工厂中，便于管理和维护。

  #### 缺点：

  1. **增加复杂性**：引入工厂模式会增加系统的复杂性，特别是在简单的场景下。
  2. **难以理解**：对于初学者来说，工厂模式可能会增加理解的难度。

  ### 总结

  工厂模式是一种强大的设计模式，适用于需要创建复杂对象的场景。通过将对象的创建与使用分离，工厂模式提高了代码的灵活性和可维护性。在设计系统时，合理运用工厂模式可以有效地管理对象的创建过程。
  -->
</head>

<body>

  <script>
    // 工厂模式是一种创建型设计模式，它提供了一种创建对象的方式，而不需要暴露对象的创建逻辑。工厂模式通过定义一个创建对象的接口，让子类决定实例化哪一个类。工厂模式使得一个类的实例化延迟到其子类。

    // 1. 类工厂模式
    class Car {
      constructor(brand) {
        this.brand = brand;
      }
    }


    class CarFactory {
      createCar(brand) {
        return new Car(brand);
      }
    }

    const carFactory = new CarFactory();
    const myCar = carFactory.createCar("Toyota");
    console.log(myCar.brand); // 输出: "Toyota"

    // 2. 函数工厂模式
    function Car(brand) {
      this.brand = brand;
    }

    function CarFactory() {
      return function (brand) {
        return new Car(brand);
      };
    }

    const carFactoryFn = CarFactory();
    const myCarFn = carFactoryFn("Toyota");
    console.log(myCarFn.brand); // 输出: "Toyota"


  </script>

</body>

</html>